/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.agilelang.generate;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JTextArea;
import org.agilelang.object.ObjectAttribute;
import org.agilelang.object.ObjectClass;
import org.agilelang.object.ObjectClassAttribute;
import org.agilelang.object.ObjectFunction;
import org.agilelang.object.ObjectParam;
import org.agilelang.object.ObjectProject;
import org.agilelang.object.Read;

/**
 *
 * @author Roderick
 */
public class AgileGenerator {

    public String name_file(String config, String name) {
        switch (config) {
            case "files":
                return Inflector.getInstance().pluralize(name).toLowerCase();
            case "FILES":
                return Inflector.getInstance().pluralize(name).toUpperCase();
            case "Files":
                return Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(name));
            case "file":
                return Inflector.getInstance().singularize(name).toLowerCase();
            case "FILE":
                return Inflector.getInstance().singularize(name).toUpperCase();
            case "File":
                return Inflector.getInstance().capitalize(Inflector.getInstance().singularize(name));
        }
        return "";
    }

    public String camel(String name) {
        return Inflector.getInstance().capitalize(name);
    }

    String path_tpl = "";
    String suf = "${";
    String posf = "}";
    String path_out = "";

    ObjectClass config = null;
    ObjectClass cls;
    Map<String, String> replace;
    Map<String, Object> data;

    public void process(String path_xml, String path_tpl, String path_out, List<ObjectClass> lists_config, JTextArea jtext) {
        ObjectProject agileproject = null;

        String functions = "";
        String attributes = "";
        this.path_tpl = path_tpl;
        this.path_out = path_out;

        Read rd = new Read();
        agileproject = rd.process(path_xml);

        //ReadConfig rc = new ReadConfig();
        //ConfigProject cp = rc.process(path_config);
        for (ObjectClass clsax : agileproject.getClasses()) {
            for (ObjectClass co : lists_config) {
                String cls_extends = "";
                cls = clsax;
                config = null;
                if (co.getType().equals(cls.getType())) {
                    config = co;
                    List<ObjectClassAttribute> class_attrs = co.getClassattributes();
                    for (ObjectClassAttribute class_attr : class_attrs) {
                        if (class_attr.getName().equals("extends")) {
                            cls_extends = class_attr.getValue();
                        }
                    }
//break;
                }

                if (config == null) {
                    continue;
                }
                if (!cls_extends.equals("")) {
                 for (ObjectClass clsax1 : agileproject.getClasses()) {
                 if (clsax1.getType().equals(cls_extends)) {
                 for ( ObjectAttribute attr : clsax1.getAttributes()) {
                 cls.addAttribute(attr);
                 }
                 }
                 }                    
                 }

                String filename = "", ext = "", template = "", pathfolder = "", pathview = "", params = "";
                Partial tpl_file = null;

                replace = new HashMap<>();
                data = new HashMap<>();
                // Atributos de la clase   
                for (ObjectFunction fun : config.getFunctions()) {
                    if (fun.getName().equals("defineTemplate")) {
                        for (ObjectParam attr : fun.getParams()) {
                            if (attr.getName().equals("filename")) {
                                filename = attr.getValue();
                            }
                            if (attr.getName().equals("ext")) {
                                ext = attr.getValue();
                            }
                            if (attr.getName().equals("template")) {
                                template = attr.getValue();
                            }
                            if (attr.getName().equals("params")) {
                                params = attr.getValue();
                            }
                            if (attr.getName().equals("pathfolder")) {
                                pathfolder = attr.getValue();
                            }
                            if (attr.getName().equals("pathview")) {
                                pathview = attr.getValue().replace("$name", cls.getNameParam());
                                File tmp = new File(path_out + File.separator + pathview);
                                if (!tmp.exists()) {
                                    if (tmp.mkdir()) {
                                        System.out.println("Directorio temporal creado : " + path_out + File.separator + pathview);
                                    } else {
                                        System.err.println("Error no se puede crear directorio temporal");
                                    }
                                } else {
                                    System.out.println("Directorio temporal ya existe : " + path_out + File.separator + pathview);
                                }
                            }
                        }
                        String[] params_a = params.split(",");
                        String[] params_set = new String[params_a.length];
                        int i_p = 0;

                        tpl_file = new Partial(path_tpl + File.separator + template);

                        for (ObjectClassAttribute attr : cls.getClassattributes()) {
                            params_set[i_p] = attr.getName();
                            i_p++;
                            if (attr.getName().equals("name")) {
                                

                                data.put("names", Inflector.getInstance().pluralize(cls.getNameParam()).toLowerCase());
                                data.put("NAMES", Inflector.getInstance().pluralize(cls.getNameParam()).toUpperCase());
                                data.put("Names", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getNameParam())));
                                data.put("name", Inflector.getInstance().singularize(cls.getNameParam()).toLowerCase());
                                data.put("NAME", Inflector.getInstance().singularize(cls.getNameParam()).toUpperCase());
                                data.put("Name", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getNameParam())));

                            } else {
                                if (attr.getName().endsWith("_list")) {
                                    tpl_file.replace(suf + attr.getName() + posf, attr.getValue());
                                    List<String> data_list = new ArrayList<>();
                                    String[] data_array = attr.getValue().split(",");
                                    for (String val : data_array) {
                                        data_list.add(val);
                                    }
                                    data.put(attr.getName(), data_list);
                                } else {
                                    tpl_file.replace(suf + attr.getName() + posf, attr.getValue());
                                    data.put(attr.getName(), attr.getValue());
                                }
                            }
                        }

                        for (int i_f = 0; i_f < params_a.length; i_f++) {
                            boolean f = false;
                            for (int i_ff = 0; i_ff < params_a.length; i_ff++) {
                                if (params_a[i_f].equals(params_set[i_ff])) {
                                    f = true;
                                    break;
                                }
                            }
                            if (!f) {
                                if (params_a[i_f].endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    data.put(params_a[i_f], data_list);
                                } else {
                                    data.put(params_a[i_f], "");
                                }
                            }
                        }
                        //----------------------------------------------------------------------------------------------
                        //ponemo todos los valores de las funciones replace en blanco
                        for (ObjectFunction fun2 : config.getFunctions()) {
                            if (!fun2.getName().equals("defineTemplate")) {
                                for (ObjectParam attr : fun2.getParams()) {
                                    if (attr.getName().equals("replace")) {
                                        data.put(attr.getValue(), "");
                                    }
                                }
                            }
                        }
//------------------------------------------------------------------------------
                        String list_attrs = "";
                        String value = "";
                        String value_f = "";int index = 0;
                        for (ObjectFunction fun1 : cls.getFunctions()) {
                            Map<String, Object> data_attr = new HashMap<String, Object>();
                            
                            if (fun1.getDefine("function_type").equals("addAttribute") && config.isFunctionAddAttrribute(fun1.getName())) {
                                Partial tpl_function = new Partial(path_tpl + File.separator + config.getFunctionAddAttrributeParam(fun1.getName(), "template"));
                                //tpl_function.replace(suf + "index" + posf, String.valueOf(index));
                                data_attr.put("index", String.valueOf(index));

                                index++;
                                for (ObjectParam attr : fun1.getParams()) {
                                    if (attr.getName().equals("name")) {
                                        data_attr.put("names", Inflector.getInstance().pluralize(attr.getValue()).toLowerCase());
                                        data_attr.put("NAMES", Inflector.getInstance().pluralize(attr.getValue()).toUpperCase());
                                        data_attr.put("Names", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getValue())));
                                        data_attr.put("name", Inflector.getInstance().singularize(attr.getValue()).toLowerCase());
                                        data_attr.put("NAME", Inflector.getInstance().singularize(attr.getValue()).toUpperCase());
                                        data_attr.put("Name", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getValue())));
                                        list_attrs = list_attrs + attr.getValue() + ",";
                                    } else {

                                        data_attr.put(attr.getName(), attr.getValue());
                                        System.err.println(">>>>>>>>>>>>>>>>>>>>>>>>>>" + suf + attr.getName() + posf);
                                    }
                                }
                                data_attr.put("clsnames", Inflector.getInstance().pluralize(cls.getNameParam()).toLowerCase());
                                data_attr.put("CLSNAMES", Inflector.getInstance().pluralize(cls.getNameParam()).toUpperCase());
                                data_attr.put("Clsnames", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getNameParam())));
                                data_attr.put("clsname", Inflector.getInstance().singularize(cls.getNameParam()).toLowerCase());
                                data_attr.put("CLSNAME", Inflector.getInstance().singularize(cls.getNameParam()).toUpperCase());
                                data_attr.put("Clsname", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getNameParam())));

                                Configuration cfg = new Configuration();
                                try {
                                    cfg.setDirectoryForTemplateLoading(new File(path_tpl));
                                    Template template_f = cfg.getTemplate(config.getFunctionAddAttrributeParam(fun1.getName(), "template"));
                                    Writer out = new StringWriter();
                                    template_f.process(data_attr, out);
                                    value_f = out.toString();
                                    //value_f += template_f.toString();

                                } catch (IOException ex) {
                                    Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                                } catch (TemplateException ex) {
                                    Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                                }
                                /*if (replace.containsKey(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"))) {
                                 value = replace.get(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"));
                                 value += tpl_function.getPtl();
                                 replace.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                                 } else {
                                 value = tpl_function.getPtl();
                                 replace.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                                 }*/

                                if (data.containsKey(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"))) {
                                    value = data.get(config.getFunctionAddAttrributeParam(fun1.getName(), "replace")).toString();
                                    value += value_f;
                                    data.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                                } else {
                                    value = value_f;
                                    data.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                                }

                                //
                            }
                        }
                        

///-------------------------------------------------------------------------------------    
                        for (ObjectFunction fun1 : config.getFunctions()) {
                            if (fun1.getName().equals("defineStatement")) {
                                String s_replace = "", s_statement = "";
                                for (ObjectParam attr : fun1.getParams()) {
                                    if (attr.getName().equals("statement")) {
                                        s_statement = attr.getValue();
                                    }
                                    if (attr.getName().equals("replace")) {
                                        s_replace = attr.getValue();
                                    }
                                }
                                s_statement = s_statement.replace("$clsnames", Inflector.getInstance().pluralize(cls.getNameParam()).toLowerCase());
                                s_statement = s_statement.replace("$CLSNAMES", Inflector.getInstance().pluralize(cls.getNameParam()).toUpperCase());
                                s_statement = s_statement.replace("$Clsnames", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getNameParam())));
                                s_statement = s_statement.replace("$clsname", Inflector.getInstance().singularize(cls.getNameParam()).toLowerCase());
                                s_statement = s_statement.replace("$CLSNAME", Inflector.getInstance().singularize(cls.getNameParam()).toUpperCase());
                                s_statement = s_statement.replace("$Clsname", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getNameParam())));

                                String[] list_params = list_attrs.split(",");
                                if (list_params.length > 1) {
                                    Pattern pattern = Pattern.compile("fun\\((.*?)\\)");
                                    Matcher matcher = pattern.matcher(s_statement);
                                    while (matcher.find()) {
                                        String s = matcher.group(1), aux = "";
                                        for (int p = 0; p < list_params.length; p++) {
                                            aux = aux + s.replace("$attr", list_params[p]) + ", ";
                                            //System.err.println(" aux " + aux);
                                        }
                                        s_statement = s_statement.replace("fun(" + s + ")", aux.substring(0, aux.length() - 2));
                                        s_statement = s_statement.replace("\\", "");
                                    }
                                }

                                data.put(s_replace, s_statement);
                            }
                        }

                        //---------------------------------------------------------------------------------------------------------------------------------------------
                        process_function(pathview);//config, cls, replace
                        //-------------------------------------------------------------------

                        for (Map.Entry mapEntry : replace.entrySet()) {
                            tpl_file.replace(suf + mapEntry.getKey() + posf, mapEntry.getValue().toString());
                            data.put(mapEntry.getKey().toString(), mapEntry.getValue().toString());
                        }

                        //UtilFile.writefile(name_file(filename, pathfolder + cls.getName()) + ext, path_out, tpl_file.getPtl());
                        jtext.append(path_out + File.separator + name_file(filename, cls.getNameParam()) + ext);
                        jtext.append("\n");
                        ///-----------------------------------------------------

                        System.out.println("FREEMAKER ----" + path_tpl);

                        Configuration cfg = new Configuration();
                        try {
                            cfg.setDirectoryForTemplateLoading(new File(path_tpl));
                            Template template_f = cfg.getTemplate(template);
                            Writer out = new OutputStreamWriter(System.out);
                            template_f.process(data, out);
                            out.flush();
                            // File output
                            System.out.println(path_out + File.separator + pathfolder + name_file(filename, cls.getNameParam()) + ext);
                            Writer file = new FileWriter(new File(path_out + File.separator + pathfolder + name_file(filename, cls.getNameParam()) + ext));
                            template_f.process(data, file);
                            file.flush();
                            file.close();
                        } catch (IOException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (TemplateException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        }

                    }
                }
            }
        }
    }

    public void process_attribute() {//ObjectClass config, ObjectClass cls, Map<String, String> replace

    }

    public void process_function(String pathview) {//ObjectClass config, ObjectClass cls, Map<String, String> replace
        int index = 0;
        for (ObjectFunction con_fun : config.getFunctions()) {
            for (ObjectFunction fun1 : cls.getFunctions()) {
                if (con_fun.getName().equals("addFunction")) {
                    if (con_fun.getDefine("type").equals(fun1.getName())) {
                    //if (con_fun.getDefine("function_type").equals("addFunction")) {
                        //fun1.getDefine("function_type").equals("addFunction") && config.isFunctionAddAttrribute(fun1.getName())
index++;
                        Partial tpl_function = new Partial(path_tpl + File.separator + con_fun.getDefine("template"));
                        //Map<String, Object> data = new HashMap<String, Object>();
                        Map<String, Object> data_fun = new HashMap<String, Object>();
                        Map<String, String> replace_aux = new HashMap<String, String>();
                        String params = con_fun.getDefine("params");
                        String[] params_a = params.split(",");
                        String[] params_set = new String[params_a.length];
                        int i_p = 0;

                        for (ObjectParam attr : fun1.getParams()) {
                            if (attr.getName().equals("function_type")) {
                                continue;
                            }
                            params_set[i_p] = attr.getName();
                            i_p++;
                            if (attr.getName().equals("name")) {
                                data_fun.put("names", Inflector.getInstance().pluralize(attr.getValue()).toLowerCase());
                                data_fun.put("NAMES", Inflector.getInstance().pluralize(attr.getValue()).toUpperCase());
                                data_fun.put("Names", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getValue())));
                                data_fun.put("name", Inflector.getInstance().singularize(attr.getValue()).toLowerCase());
                                data_fun.put("NAME", Inflector.getInstance().singularize(attr.getValue()).toUpperCase());
                                data_fun.put("Name", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getValue())));

                            } else {
                                if (attr.getName().endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    String[] data_array = attr.getValue().split(",");
                                    for (String val : data_array) {
                                        data_list.add(val);
                                    }
                                    data_fun.put(attr.getName(), data_list);
                                } else {
                                    data_fun.put(attr.getName(), attr.getValue());
                                    /*data_fun.put(Inflector.getInstance().pluralize(attr.getName()).toLowerCase(), Inflector.getInstance().pluralize(attr.getValue()).toLowerCase());
                                     data_fun.put(Inflector.getInstance().pluralize(attr.getName()).toUpperCase(), Inflector.getInstance().pluralize(attr.getValue()).toUpperCase());
                                     data_fun.put(Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getName())), Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getValue())));
                                     data_fun.put(Inflector.getInstance().singularize(attr.getName()).toLowerCase(), Inflector.getInstance().singularize(attr.getValue()).toLowerCase());
                                     data_fun.put(Inflector.getInstance().singularize(attr.getName()).toUpperCase(), Inflector.getInstance().singularize(attr.getValue()).toUpperCase());
                                     data_fun.put(Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getName())), Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getValue())));
                                     */
                                }

                            }
                        }
                        data_fun.put("clsnames", Inflector.getInstance().pluralize(cls.getName()).toLowerCase());
                        data_fun.put("CLSNAMES", Inflector.getInstance().pluralize(cls.getName()).toUpperCase());
                        data_fun.put("Clsnames", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getName())));
                        data_fun.put("clsname", Inflector.getInstance().singularize(cls.getName()).toLowerCase());
                        data_fun.put("CLSNAME", Inflector.getInstance().singularize(cls.getName()).toUpperCase());
                        data_fun.put("Clsname", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getName())));

                        for (String params_a1 : params_a) {
                            boolean f = false;
                            for (int i_ff = 0; i_ff < params_a.length; i_ff++) {
                                if (params_a1.equals(params_set[i_ff])) {
                                    f = true;
                                    break;
                                }
                            }
                            if (!f) {
                                if (params_a1.endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    data_fun.put(params_a1, data_list);
                                } else {
                                    data_fun.put(params_a1, "");
                                }
                            }
                        }

                        String template_s = "", value = "", value_f = "";
                        Configuration cfg = new Configuration();
                        try {
                            cfg.setDirectoryForTemplateLoading(new File(path_tpl));
                            Template template_f = cfg.getTemplate(con_fun.getDefine("template"));
                            Writer out = new StringWriter();
                            template_f.process(data_fun, out);
                            value_f = out.toString();
                            System.err.println("Template" + value_f);
                        } catch (IOException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (TemplateException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        if (data.containsKey(con_fun.getDefine("replace"))) {
                            value = data.get(con_fun.getDefine("replace")).toString();
                            value = value + value_f;
                            data.put(con_fun.getDefine("replace"), value);
                        } else {
                            value = value_f;
                            data.put(con_fun.getDefine("replace"), value);
                        }
                    }
                }
            }
        }
        
        data.put("number", index);
    }

    public void process_function2(String pathview) {//ObjectClass config, ObjectClass cls, Map<String, String> replace
        for (ObjectFunction con_fun : config.getFunctions()) {
            for (ObjectFunction fun1 : cls.getFunctions()) {

                if (con_fun.getDefine("type").equals(fun1.getName()) && fun1.getDefine("function_type").equals("addFunction")) {
                    //if (con_fun.getDefine("function_type").equals("addFunction")) {
                    //fun1.getDefine("function_type").equals("addFunction") && config.isFunctionAddAttrribute(fun1.getName())
                    if (con_fun.getName().equals("addFunction")) {

                        Partial tpl_function = new Partial(path_tpl + File.separator + con_fun.getDefine("template"));
                        //Map<String, Object> data = new HashMap<String, Object>();
                        Map<String, Object> data_fun = new HashMap<String, Object>();
                        Map<String, String> replace_aux = new HashMap<String, String>();
                        String params = con_fun.getDefine("params");
                        String[] params_a = params.split(",");
                        String[] params_set = new String[params_a.length];
                        int i_p = 0;

                        for (ObjectParam attr : fun1.getParams()) {
                            if (attr.getName().equals("function_type")) {
                                continue;
                            }
                            params_set[i_p] = attr.getName();
                            i_p++;
                            if (attr.getName().equals("name")) {
                                data_fun.put("names", Inflector.getInstance().pluralize(attr.getValue()).toLowerCase());
                                data_fun.put("NAMES", Inflector.getInstance().pluralize(attr.getValue()).toUpperCase());
                                data_fun.put("Names", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getValue())));
                                data_fun.put("name", Inflector.getInstance().singularize(attr.getValue()).toLowerCase());
                                data_fun.put("NAME", Inflector.getInstance().singularize(attr.getValue()).toUpperCase());
                                data_fun.put("Name", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getValue())));

                            } else {
                                if (attr.getName().endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    String[] data_array = attr.getValue().split(",");
                                    for (String val : data_array) {
                                        data_list.add(val);
                                    }
                                    data_fun.put(attr.getName(), data_list);
                                } else {
                                    data_fun.put(attr.getName(), attr.getValue());
                                    /*data_fun.put(Inflector.getInstance().pluralize(attr.getName()).toLowerCase(), Inflector.getInstance().pluralize(attr.getValue()).toLowerCase());
                                     data_fun.put(Inflector.getInstance().pluralize(attr.getName()).toUpperCase(), Inflector.getInstance().pluralize(attr.getValue()).toUpperCase());
                                     data_fun.put(Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getName())), Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(attr.getValue())));
                                     data_fun.put(Inflector.getInstance().singularize(attr.getName()).toLowerCase(), Inflector.getInstance().singularize(attr.getValue()).toLowerCase());
                                     data_fun.put(Inflector.getInstance().singularize(attr.getName()).toUpperCase(), Inflector.getInstance().singularize(attr.getValue()).toUpperCase());
                                     data_fun.put(Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getName())), Inflector.getInstance().capitalize(Inflector.getInstance().singularize(attr.getValue())));
                                     */
                                }

                            }
                        }
                        data_fun.put("clsnames", Inflector.getInstance().pluralize(cls.getName()).toLowerCase());
                        data_fun.put("CLSNAMES", Inflector.getInstance().pluralize(cls.getName()).toUpperCase());
                        data_fun.put("Clsnames", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getName())));
                        data_fun.put("clsname", Inflector.getInstance().singularize(cls.getName()).toLowerCase());
                        data_fun.put("CLSNAME", Inflector.getInstance().singularize(cls.getName()).toUpperCase());
                        data_fun.put("Clsname", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getName())));

                        for (String params_a1 : params_a) {
                            boolean f = false;
                            for (int i_ff = 0; i_ff < params_a.length; i_ff++) {
                                if (params_a1.equals(params_set[i_ff])) {
                                    f = true;
                                    break;
                                }
                            }
                            if (!f) {
                                if (params_a1.endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    data_fun.put(params_a1, data_list);
                                } else {
                                    data_fun.put(params_a1, "");
                                }
                            }
                        }

                        String template_s = "", value = "", value_f = "";
                        Configuration cfg = new Configuration();
                        try {
                            cfg.setDirectoryForTemplateLoading(new File(path_tpl));
                            Template template_f = cfg.getTemplate(con_fun.getDefine("template"));
                            Writer out = new StringWriter();
                            template_f.process(data_fun, out);
                            value_f = out.toString();
                            System.err.println("Template" + value_f);
                        } catch (IOException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (TemplateException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        if (data.containsKey(con_fun.getDefine("replace"))) {
                            value = data.get(con_fun.getDefine("replace")).toString();
                            value = value + value_f;
                            data.put(con_fun.getDefine("replace"), value);
                        } else {
                            value = value_f;
                            data.put(con_fun.getDefine("replace"), value);
                        }

                        /*

                         if (data.containsKey(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"))) {
                         value = data.get(config.getFunctionAddAttrributeParam(fun1.getName(), "replace")).toString();
                         value += value_f;
                         data.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                         } else {
                         value = value_f;
                         data.put(config.getFunctionAddAttrributeParam(fun1.getName(), "replace"), value);
                         }*/
                        //functions += tpl_function.getPtl();
                        /*if (replace.containsKey(con_fun.getDefine("replace"))) {
                         String value = replace.get(con_fun.getDefine("replace"));
                            
                         replace.put(con_fun.getDefine("replace"), template_s);
                         } else {
                            
                         replace.put(con_fun.getDefine("replace"), template_s);
                         }*/
                    }

                    if (con_fun.getName().equals("addView")) {
                        String str_file = "";
                        Map<String, Object> data = new HashMap<String, Object>();
                        Partial tpl_function = new Partial(path_tpl + File.separator + con_fun.getDefine("template"));

                        String params = con_fun.getDefine("params");
                        String[] params_a = params.split(",");
                        String[] params_set = new String[params_a.length];
                        int i_p = 0;

                        for (ObjectParam attr : fun1.getParams()) {
                            if (attr.getName().equals("function_type")) {
                                continue;
                            }
                            params_set[i_p] = attr.getName();
                            i_p++;
                            if (attr.getName().equals("name")) {
                                str_file = attr.getValue();
                                data.put("names", Inflector.getInstance().pluralize(cls.getName()).toLowerCase());
                                data.put("NAMES", Inflector.getInstance().pluralize(cls.getName()).toUpperCase());
                                data.put("Names", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getName())));
                                data.put("name", Inflector.getInstance().singularize(cls.getName()).toLowerCase());
                                data.put("NAME", Inflector.getInstance().singularize(cls.getName()).toUpperCase());
                                data.put("Name", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getName())));
                                //tpl_function.replace(suf + attr.getName() + posf, attr.getValue());
                            } else {
                                if (attr.getName().endsWith("_list")) {
                                    tpl_function.replace(suf + attr.getName() + posf, attr.getValue());
                                    List<String> data_list = new ArrayList<>();
                                    String[] data_array = attr.getValue().split(",");
                                    for (String val : data_array) {
                                        data_list.add(val);
                                    }
                                    data.put(attr.getName(), data_list);
                                } else {
                                    tpl_function.replace(suf + attr.getName() + posf, attr.getValue());
                                    data.put(attr.getName(), attr.getValue());
                                }

                            }
                        }

                        data.put("clsnames", Inflector.getInstance().pluralize(cls.getName()).toLowerCase());
                        data.put("CLSNAMES", Inflector.getInstance().pluralize(cls.getName()).toUpperCase());
                        data.put("Clsnames", Inflector.getInstance().capitalize(Inflector.getInstance().pluralize(cls.getName())));
                        data.put("clsname", Inflector.getInstance().singularize(cls.getName()).toLowerCase());
                        data.put("CLSNAME", Inflector.getInstance().singularize(cls.getName()).toUpperCase());
                        data.put("Clsname", Inflector.getInstance().capitalize(Inflector.getInstance().singularize(cls.getName())));

                        for (String params_a1 : params_a) {
                            boolean f = false;
                            for (int i_ff = 0; i_ff < params_a.length; i_ff++) {
                                if (params_a1.equals(params_set[i_ff])) {
                                    f = true;
                                    break;
                                }
                            }
                            if (!f) {
                                if (params_a1.endsWith("_list")) {
                                    List<String> data_list = new ArrayList<>();
                                    data.put(params_a1, data_list);
                                } else {
                                    data.put(params_a1, "");
                                }
                            }
                        }

                        /*for (Map.Entry mapEntry : replace.entrySet()) {
                         tpl_function.replace(suf + mapEntry.getKey() + posf, mapEntry.getValue().toString());
                         }*/
                        //UtilFile.writefile(pathview + con_fun.getDefine("pathfolder") + str_file + con_fun.getDefine("ext"), path_out, tpl_function.getPtl());
                        System.out.println("FREEMAKER ----" + path_tpl);

                        Configuration cfg = new Configuration();
                        try {
                            cfg.setDirectoryForTemplateLoading(new File(path_tpl));
                            Template template_f = cfg.getTemplate(con_fun.getDefine("template"));
                            Writer out = new OutputStreamWriter(System.out);
                            template_f.process(data, out);
                            out.flush();
                            // File output
                            System.out.println(path_out + File.separator + pathview + con_fun.getDefine("pathfolder") + str_file + con_fun.getDefine("ext") + "fv");
                            Writer file = new FileWriter(new File(path_out + File.separator + pathview + con_fun.getDefine("pathfolder") + str_file + con_fun.getDefine("ext") + "fv"));
                            template_f.process(data, file);
                            file.flush();
                            file.close();
                        } catch (IOException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (TemplateException ex) {
                            Logger.getLogger(AgileGenerator.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
        }
    }

    public static void main(String ar[]) {
        String path_xml = "E:\\agile\\AgileLang\\Test\\out.xml";
        String path_tpl = "E:\\agile\\AgileLang\\Test\\tmpl_java";
        String path_out = "E:\\agile\\AgileLang\\Test\\out";
        String path_config = "E:\\agile\\AgileLang\\Test\\config_java.xml";
        AgileGenerator ag = new AgileGenerator();
        //ag.process(path_xml, path_tpl, path_out, path_config, new JTextArea());
    }

}
